import * as utils from '../utils/index';
import shapeStyle from '../utils/defaultStyle';
import _ from 'lodash';
import Anchor from '../item/anchor';
const _util = require('@antv/util');

import { nodeDefaultOptions } from '../utils/defaultOptions';

const BaseNodeDef = {
    options: {
        ...nodeDefaultOptions,
    },
    shapeType: 'base-node',
    drawAnchor(cfg, group, excludeIndexs) {
        const bbox = group.getFirst().getBBox();
        try {
            this.getAnchorPoints(cfg).forEach((p, i) => {
                if (Array.isArray(excludeIndexs) && excludeIndexs.includes(i)) {
                    return;
                }
                const anchorContainer = group.addGroup();
                new Anchor({
                    group: anchorContainer,
                    index: i,
                    model: {
                        style: {
                            x: bbox.minX + bbox.width * p[0],
                            y: bbox.minY + bbox.height * p[1],
                        },
                    },
                });
                group.anchorShapes.push(anchorContainer);
            });
        } catch (error) {
            console.error(error, '错误的锚点绘制');
        }
    },
    initAnchor(cfg, group) {
        // 用来装锚点 item 的数组
        group.anchorShapes = [];
        //excludeIndexs 排除绘制锚点的索引，拖拽时调用规则
        group.showAnchor = (g, excludeIndexs) => {
            this.drawAnchor(cfg, g, excludeIndexs);
        };
        // 清除所有锚点的 item
        group.clearAnchor = (g) => {
            g.anchorShapes && g.anchorShapes.forEach((a) => a.remove());
            g.anchorShapes = [];
        };
        group.clearHotpotActived = (g) => {
            g.anchorShapes &&
                g.anchorShapes.forEach((a) => {
                    if (a.isAnchor) a.setHotspotActived(false);
                });
        };
        group.getAllAnchors = () => {
            return group.anchorShapes.map((c) => {
                c.filter((a) => a.isAnchor);
            });
        };
        group.getAnchor = (i) => {
            return group.anchorShapes.filter((a) => a.get('index') === i);
        };
    },
    drawShape(cfg, group) {
        const style = this.getShapeStyle(cfg);
        const keyShape = group.addShape('rect', {
            attrs: {
                ...style,
            },
            name: 'rect-shape',
        });

        // 左侧色条
        const { x, y, radius = 0 } = style;
        const preRect = this.getOptions(cfg).preRect;
        if (preRect.show) {
            group.addShape('path', {
                attrs: {
                    path: [
                        ['M', x, y + radius],
                        ['L', x, y + style.height - radius],
                        ['A', radius, radius, 0, 0, 0, x + radius, y + style.height],
                        ['L', x + radius, y + style.height],
                        ['L', x + radius, y],
                        ['L', x + radius, y],
                        ['A', radius, radius, 0, 0, 0, x, y + radius],
                    ],
                    fill: preRect.fill,
                },
                name: 'preRect',
                draggable: true,
            });
        }

        this.drawLogoIcon(cfg, group);
        this.drawStateIcon(cfg, group);
        this.drawLabel(cfg, group);

        this.initAnchor(cfg, group);
        return keyShape;
    },
    drawLogoIcon(cfg, group) {
        const logoIcon = this.getOptions(cfg).logoIcon;
        const style = this.getShapeStyle(cfg);
        const { x, y, height } = style;

        if (logoIcon.show) {
            group.addShape('image', {
                attrs: {
                    x: x + logoIcon.offset,
                    y: y + (height - logoIcon.height) / 2, // 上下居中
                    ...logoIcon,
                },
                name: 'logo-icon',
                draggable: true,
            });
        }
    },
    drawStateIcon(cfg, group) {
        const stateIcon = this.getOptions(cfg).stateIcon;
        const style = this.getShapeStyle(cfg);
        const { x, y, width, height } = style;

        // 暂时写在这里面了
        if (stateIcon.show) {
            if (!stateIcon.loading) {
                group.addShape('image', {
                    attrs: {
                        x: x + width - stateIcon.width + stateIcon.offset,
                        y: y + (height - stateIcon.height) / 2,
                        width: stateIcon.width,
                        height: stateIcon.height,
                        isState: true,
                        ...stateIcon,
                    },
                    name: 'state-icon',
                    draggable: true,
                });
            } else {
                // loading 状态需要
                const statePosition = {
                    x: x + width - 30, // 三个⚪的距离和
                    y: y + height / 2,
                };
                const circle1 = group.addShape('circle', {
                    attrs: {
                        x: statePosition.x,
                        y: statePosition.y,
                        r: 3,
                        fill: '#9a9a9a',
                        opacity: 1,
                    },
                    name: 'circle-shape1',
                });
                const circle2 = group.addShape('circle', {
                    attrs: {
                        x: statePosition.x + 10,
                        y: statePosition.y,
                        r: 3,
                        fill: '#9a9a9a',
                        opacity: 1,
                    },
                    name: 'circle-shape2',
                });
                const circle3 = group.addShape('circle', {
                    attrs: {
                        x: statePosition.x + 20,
                        y: statePosition.y,
                        r: 3,
                        fill: '#9a9a9a',
                        opacity: 1,
                    },
                    name: 'circle-shape3',
                });
                circle1.animate(
                    {
                        // 动画重复
                        repeat: true,
                        // 每一帧的操作，入参 ratio：这一帧的比例值（Number）。返回值：这一帧需要变化的参数集（Object）。
                        onFrame(ratio) {
                            return {
                                opacity: 0.3 + ratio * 0.7,
                            };
                        },
                    },
                    900
                );
                circle2.animate(
                    {
                        // 动画重复
                        repeat: true,
                        // 每一帧的操作，入参 ratio：这一帧的比例值（Number）。返回值：这一帧需要变化的参数集（Object）。
                        onFrame(ratio) {
                            return {
                                opacity: 0.3 + ratio * 0.7,
                            };
                        },
                    },
                    900,
                    'easeLinear',
                    null,
                    300
                );
                circle3.animate(
                    {
                        // 动画重复
                        repeat: true,
                        // 每一帧的操作，入参 ratio：这一帧的比例值（Number）。返回值：这一帧需要变化的参数集（Object）。
                        onFrame(ratio) {
                            return {
                                opacity: 0.3 + ratio * 0.7,
                            };
                        },
                    },
                    900,
                    'easeLinear',
                    null,
                    600
                );
            }
        }
    },
    // 详情看源码 shapeBase
    drawLabel(cfg, group) {
        const options = this.getOptions(cfg),
            labelCfg = options.labelCfg,
            logoIcon = options.logoIcon,
            fontStyle = labelCfg.style;

        const size = this.getSize(cfg),
            width = size[0];

        var offsetX = -width / 2 + labelCfg.offset;

        if (logoIcon.show) {
            offsetX = -width / 2 + logoIcon.width + labelCfg.offset;
        }

        // labelMaxWidth = Math.max(labelMaxWidth - labelCfg.offset * 2, 0);
        // this.labelMaxWidth = labelMaxWidth;

        // const fittingLabel = utils.suitableString(label, labelMaxWidth, labelCfg.fontSize);
        // leftX += labelCfg.offset;

        // 名称文本
        const label = group.addShape('text', {
            attrs: {
                x: offsetX,
                text: cfg.label,
                ...fontStyle,
            },
            className: 'rect-label',
            draggable: true,
        });
        return label;
    },

    // 锚点
    getAnchorPoints(cfg) {
        if (!cfg || !cfg.anchorConfig)
            return [
                [0.5, 0],
                [0.5, 1],
            ];

        return [
            ...this._getSingleAnchorPoints(cfg.anchorConfig, 'top'),
            ...this._getSingleAnchorPoints(cfg.anchorConfig, 'bottom'),
            ...this._getSingleAnchorPoints(cfg.anchorConfig, 'left'),
            ...this._getSingleAnchorPoints(cfg.anchorConfig, 'right'),
        ];
    },
    _getSingleAnchorPoints(anchorConfig, type) {
        let singleAnchorPoints = [];
        if (anchorConfig && anchorConfig[type]) {
            const singleAnchorConfig = anchorConfig[type];
            const singleType = typeof singleAnchorConfig;
            if (singleType === 'number') {
                new Array(singleAnchorConfig).forEach((item, i) => {
                    const ratio = (i + 1) * (1 / (singleAnchorConfig + 1));
                    let coordinate;
                    switch (type) {
                        case 'top':
                            coordinate = [ratio, 0];
                            break;
                        case 'bottom':
                            coordinate = [ratio, 1];
                            break;
                        case 'left':
                            coordinate = [0, ratio];
                            break;
                        case 'right':
                            coordinate = [1, ratio];
                            break;
                        default:
                            break;
                    }
                    if (coordinate) {
                        singleAnchorPoints.push(coordinate);
                    }
                });
            } else if (Array.isArray(singleAnchorConfig)) {
                const size = singleAnchorConfig.length;
                singleAnchorConfig.forEach((item, i) => {
                    const ratio = (i + 1) * (1 / (size + 1));
                    let coordinate;
                    switch (type) {
                        case 'top':
                            coordinate = [ratio, 0];
                            break;
                        case 'bottom':
                            coordinate = [ratio, 1];
                            break;
                        case 'left':
                            coordinate = [0, ratio];
                            break;
                        case 'right':
                            coordinate = [1, ratio];
                            break;
                        default:
                            break;
                    }
                    if (coordinate) {
                        singleAnchorPoints.push(coordinate);
                        // singleAnchorPoints.push({
                        //     label: item.label,
                        //     coordinate
                        // });
                    }
                });
            }
        }
        return singleAnchorPoints;
    },
    update(cfg, item) {
        console.error('更新了节点 update');
        const group = item.getContainer();
        const customOptions = this || {};
        const { labelCfg: defaultLabelCfg, label: defaultLabel } = this.options;
        const { labelCfg: customLabelCfg, label: customLabel } = customOptions;

        const labelCfg = _util.deepMix({}, defaultLabelCfg, customLabelCfg, cfg.labelCfg);
        const label = cfg.label || customLabel || defaultLabel;
        const text = group.findByClassName('rect-label');
        const fittingLabel = utils.suitableString(label, this.labelMaxWidth, labelCfg.fontSize);
        if (text) {
            text.attr({
                text: fittingLabel,
                ...labelCfg,
            });
        }
        //如果需要再updateItem时更新其他元素，再根据需要做实现

        //更新的时候需要还原节点的状态，否则会导致状态的错误触发
        item.setState('show-anchor', false);
        item.setState('hover', false);
        item.setState('selected', false);
    },
    // 设置状态
    setState(name, value, item) {
        const cfg = item.getModel();
        const options = this.getOptions(cfg);
        const group = item.getContainer();

        if (name === 'selected') {
            const s = item.getStateStyle('selected');
            const rect = group.getChildByIndex(0);
            if (value) {
                rect.attr(s);
            } else {
                rect.attr(options.style); // 这样可能会影响到其他状态的样式，具体看需求。
            }
        }
        if (name === 'show-anchor') {
            if (value) {
                group.showAnchor(group);
            } else {
                group.clearAnchor(group);
            }
        } else if (name === 'selected') {
            const s = item.getStateStyle('selected');
            const rect = group.getChildByIndex(0); // keyshape
            if (value) {
                rect.attr(s);
            } else {
                rect.attr(options.style);
            }
        } else if (name === 'hover') {
            const rect = group.getChildByIndex(0);
            const text = group.getChildByIndex(1); //
            if (value) {
                const s = item.getStateStyle('hover');
                rect.attr(s);
                if (text) text.attr('cursor', 'move');
            } else {
                const originStyle = options.style;
                rect.attr('lineWidth', originStyle.lineWidth);
                rect.attr('stroke', originStyle.stroke);
                rect.attr('cursor', 'default');
                if (text) text.attr('cursor', 'default');
            }
        } else if (name === 'warn') {
            const preRect = group.find((item) => {
                return item.get('name') === 'preRect';
            });
            if (value) {
                preRect.attr('fill', '#FADB14'); // 警告⚠ 黄色标识
            } else {
                preRect.attr(options.preRect);
            }
        }
    },
};

export default function(G6) {
    G6.registerNode('base-node', BaseNodeDef, 'single-node');
}
